package com.study.cloud.gateway.core.context;

import com.study.cloud.gateway.common.rule.Rule;
import io.netty.channel.ChannelHandlerContext;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;

/**
 * 核心上下文的基础实现
 * @author wangwancheng
 * @create 2025/7/17 14:15
 */
public class BaseContext implements IContext{

    /**
     * 转发协议
     */
    protected final String protocol;

    /**
     * netty上下文
     */
    protected final ChannelHandlerContext nettyCtx;

    /**
     * 是否保持长链接
     */
    protected final boolean keepAlive;

    /**
     * 上下文状态
     */
    private volatile int status = RUNING;

    /**
     * 上下文参数集合
     */
    private final Map<String, Object> attributes = new HashMap<>();

    /**
     * 请求过程中异常
     */
    private Throwable throwable;

    /**
     * 是否已经释放资源
     */
    protected final AtomicBoolean requestReleased = new AtomicBoolean(false);

    /**
     * 存放回调函数
     */
    private List<Consumer<IContext>> completeCallbacks;

    public BaseContext(String protocol, ChannelHandlerContext nettyCtx, boolean keepAlive) {
        this.protocol = protocol;
        this.nettyCtx = nettyCtx;
        this.keepAlive = keepAlive;
    }






    @Override
    public void runing() {
        status = RUNING;
    }

    @Override
    public void written() {
        status = WRITTEN;
    }

    @Override
    public void complete() {
        status = COMPLETE;
    }

    @Override
    public void terminated() {
        status = TERMINATED;
    }

    @Override
    public boolean isRunning() {
        return status == RUNING;
    }

    @Override
    public boolean isWritten() {
        return status == WRITTEN;
    }

    @Override
    public boolean isComplete() {
        return status == COMPLETE;
    }

    @Override
    public boolean isTerminated() {
        return status == TERMINATED;
    }

    @Override
    public String getProtocol() {
        return protocol;
    }

    @Override
    public Rule getRule() {
        return null;
    }

    @Override
    public Object getRequest() {
        return null;
    }

    @Override
    public Object getResponse() {
        return null;
    }

    @Override
    public Throwable getThrowable() {
        return this.throwable;
    }

    @Override
    public Object getAttribute(Map<String, Object> key) {
        return null;
    }

    @Override
    public void setRule(Rule rule) {

    }

    @Override
    public void setResponse() {

    }

    @Override
    public void setThrowable(Throwable throwable) {
        this.throwable = throwable;
    }

    @Override
    public void setAttribute(String key, Object value) {
        this.attributes.put(key, value);
    }

    @Override
    public ChannelHandlerContext getNettyCtx() {
        return this.nettyCtx;
    }

    @Override
    public boolean isKeepAlive() {
        return this.keepAlive;
    }

    @Override
    public void releaseRequest() {
        this.requestReleased.compareAndSet(false,true);
    }

    @Override
    public void setCallback(Consumer<IContext> callback) {
        if (completeCallbacks == null){
            completeCallbacks = new ArrayList<>();
        }
        completeCallbacks.add(callback);
    }

    @Override
    public void invokeCompleteCallback() {
        if (completeCallbacks != null){
            completeCallbacks.forEach(callback -> callback.accept(this));
        }
    }
}
